<?php

namespace App\Models;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;

class Didi
{
    private $config = null;

    public function __construct()
    {
        $this->config = config('didi');
    }

    public function generateLink($source_id, $activity_id, $link_type = 'h5')
    {
        $url = $this->config['domain'] . '/openapi/v1.0/link/generate';

        $source_id = (string)$source_id;
        $activity_id = (int)$activity_id;
        $Timestamp = time();

        $param_to_sign = [
            "App-Key" => $this->config['app_key'],
            "Timestamp" => $Timestamp,
            "source_id" => $source_id,
            "activity_id" => $activity_id,
            "link_type" => $link_type,
            "promotion_id" => $this->config['promotion_id'],
        ];

        $header = [
            "App-Key" => $this->config['app_key'],
            "Timestamp" => $Timestamp,
            "Sign" => $this->get_sign($param_to_sign),
            "Content-Type" => 'application/json',
        ];
        $result = Http::withHeaders($header)->post($url, [
            "source_id" => $source_id,
            "activity_id" => $activity_id,
            "link_type" => $link_type,
            "promotion_id" => $this->config['promotion_id'],
        ])->json();
        return $result['data'] ?? [];
    }

    public function generateCode($source_id, $activity_id, $dsi, $type = 'h5')
    {
        $url = $this->config['domain'] . '/openapi/v1.0/code/generate';

        $source_id = (string)$source_id;
        $activity_id = (int)$activity_id;
        $Timestamp = time();

        $param_to_sign = [
            "App-Key" => $this->config['app_key'],
            "Timestamp" => $Timestamp,
            "dsi" => $dsi,
            "source_id" => $source_id,
            "activity_id" => $activity_id,
            "type" => $type,
            "promotion_id" => $this->config['promotion_id'],
        ];

        $header = [
            "App-Key" => $this->config['app_key'],
            "Timestamp" => $Timestamp,
            "Sign" => $this->get_sign($param_to_sign),
        ];
        $result = Http::withHeaders($header)->get($url, [
            "source_id" => $source_id,
            "activity_id" => $activity_id,
            "type" => $type,
            "dsi" => $dsi,
            "promotion_id" => $this->config['promotion_id'],
        ])->json();
        return $result['data'] ?? [];
    }

    public function generatePoster($source_id, $activity_id, $dsi)
    {
        $url = $this->config['domain'] . '/openapi/v1.0/poster/generate';

        $source_id = (string)$source_id;
        $activity_id = (int)$activity_id;
        $Timestamp = time();

        $param_to_sign = [
            "App-Key" => $this->config['app_key'],
            "Timestamp" => $Timestamp,
            "source_id" => $source_id,
            "activity_id" => $activity_id,
            "promotion_id" => $this->config['promotion_id'],
            "dsi" => $dsi,
        ];

        $header = [
            "App-Key" => $this->config['app_key'],
            "Timestamp" => $Timestamp,
            "Sign" => $this->get_sign($param_to_sign),
        ];
        $result = Http::withHeaders($header)->get($url, [
            "source_id" => $source_id,
            "activity_id" => $activity_id,
            "dsi" => $dsi,
            "promotion_id" => $this->config['promotion_id'],
        ])->json();
        return $result['data'] ?? [];
    }

    public function generatePwd($source_id, $activity_id)
    {
        $url = $this->config['domain'] . '/openapi/v1.0/exchange/pwd/generate';

        $source_id = (string)$source_id;
        $activity_id = (int)$activity_id;
        $Timestamp = time();

        $param_to_sign = [
            "App-Key" => $this->config['app_key'],
            "Timestamp" => $Timestamp,
            "source_id" => $source_id,
            "activity_id" => $activity_id,
            "pwd_type" => 'coupon',
            "promotion_id" => $this->config['promotion_id'],
        ];

        $header = [
            "App-Key" => $this->config['app_key'],
            "Timestamp" => $Timestamp,
            "Sign" => $this->get_sign($param_to_sign),
        ];
        $result = Http::withHeaders($header)->get($url, [
            "source_id" => $source_id,
            "activity_id" => $activity_id,
            "pwd_type" => 'coupon',
            "promotion_id" => $this->config['promotion_id'],
        ])->json();
        return $result['data'] ?? [];
    }

    public function generate($source_id, $activity_id)
    {
        $data = Cache::get($source_id . ":" . $activity_id);
        if ($data) {
            return $data;
        }
        $link = $this->generateLink($source_id, $activity_id);
        if (!$link) {
            return [];
        }
        $link_mini = $this->generateLink($source_id, $activity_id, 'mini');
        $code = $this->generateCode($source_id, $activity_id, $link['dsi']);
        $poster = $this->generatePoster($source_id, $activity_id, $link['dsi']);

        $data = [
            'link_h5' => $link['link'],
            'app_id' => $link_mini['app_id'],
            'app_source' => $link_mini['app_source'],
            'link_mini' => $link_mini['link'],
            'code_link' => $code['code_link'],
            'poster_link' => $poster['poster_link'],
        ];

        Cache::put($source_id . ":" . $activity_id, $data, 60 * 60 * 24);
        return $data;
    }

    public static function callback($data)
    {
        if (empty($data['source_id'])){
            return ['code' => 1, 'msg' => 'source_id is empty'];
        }
        PlatformCallback::query()->create([
            'platform' => $data['platform'],
            'body' => json_encode($data),
            'source_id' => $data['source_id'],
        ]);
        return ['code' => 0, 'msg' => 'ok'];
    }

    public function reward_callback()
    {

    }

    private function get_sign($pr)
    {
        $accesskey = $this->config['access_key'];
        ksort($pr);
        $ptr = array();
        foreach ($pr as $key => $val) {
            array_push($ptr, $key . "=" . $val);
        }
        $source = urlencode(implode("&", $ptr)) . $accesskey;
        $sign = urlencode(base64_encode(sha1($source)));
        return $sign;
    }
}
